#!/usr/bin/python

import sys, time, socket
from threading import Thread
from daemon import Daemon

HOST = 'localhost'
PORT = 29093 # arbitrary port
CARDS = 2
TIMEOUT = 2.0

class cardStack:
    def __init__ (self, nCards):
        self.nCards = nCards
        self.stack = range (self.nCards-1, -1, -1)
    def pop (self):
        if len (self.stack) == 0:
            raise Error ('out of cards!')
        return self.stack.pop ()
    def push (self, c):
        if c < 0 or c >= self.nCards:
            raise Error ('invalid card number')
        elif c in self.stack:
            raise Error ('problem organizing cards')
        else:
            self.stack.append (c)

class scheduler (Daemon):
    def __init__ (self):
        Daemon.__init__ (self)
        self.c = cardStack (CARDS)
        self.running = True

    def check (self, n):
        return self.q[n]

    def dispatch (self, conn, n):
        t = Thread (target=self.monitor, args=(conn,n))
        t.setDaemon (True)
        t.start ()

    def monitor (self, conn, n):
        conn.settimeout (TIMEOUT)
        while 1:
            data = conn.recv (1024)
            if data == 'done': break
        conn.close()
        self.c.push (n) # put the card back

    def run (self):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
        s.bind((HOST, PORT))
        s.listen(2)
        while self.running: # Running is terminated by daemon class
            conn, addr = s.accept() # poll for next open request 
            req = conn.recv(1024)
            if req == 'please':
                try:
                    card = self.c.pop ()
                    conn.send (str(card))
                    self.dispatch (conn, card) # start monitoring thread
                except:
                    conn.send ('Out of cards.')
            else:
                conn.send ('reject')

if __name__ == '__main__':
    usage = 'usage: '+sys.argv[0]+' start|stop|restart'

    s = scheduler ()
    if len (sys.argv) == 2:
        if sys.argv[1] == 'start':
            s.start ()
        elif sys.argv[1] == 'stop':
            s.stop ()
        elif sys.argv[1] == 'restart':
            s.restart ()
        else:
            print 'unknown argument;', usage
            sys.exit (1)
    else:
        print usage
        sys.exit (1)
